package com.justgame.project.mq.consumer.system;

import com.justgame.mq.client.constant.SystemQueueConstant;
import com.justgame.project.cloud.common.constant.Const;
import com.justgame.project.cloud.common.constant.Regex;
import com.justgame.project.cloud.common.enums.TimeEnum;
import com.justgame.project.cloud.common.util.*;
import com.rabbitmq.client.Channel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author ZhouWeiBo
 * @create 2022/5/30
 */
@Slf4j
@Component
@AllArgsConstructor
public class EmailAuthConsumer {
    private final RedisUtils redisUtils;

    @RabbitHandler
    @RabbitListener(queues = SystemQueueConstant.SYSTEM_EMAIL_AUTH_QUEUE)
    public void processSendEmail(Channel channel, Message message) throws IOException {
        try {
            /* 消息幂等性，防止重复消费 */
            if (RabbitHelper.isExecutedMsg(message)) {
                return;
            }
            String mail = new String(message.getBody());
            /* 格式不匹配处理 */
            if(mail.startsWith("\"") && mail.endsWith("\"")){
                mail = mail.substring(1,mail.length() - 1);
            }
            if (StringUtils.isBlank(mail) || !Regex.isEmail(mail)) {
                return;
            }
            /* 判断发送邮件次数 */
            int hasSendCount = Integer.parseInt(redisUtils.get(Const.EMAIL_VALIDATION_COUNT + mail, "0"));
            if (hasSendCount >= Const.EMAIL_VALIDATION_MAX_COUNT) {
                return;
            }
            /* 生成发送的验证码 */
            String code = OrderUtil.randomNumberStr(6);
            log.info("正在向【{}】发送验证码：{}！", mail, code);
            redisUtils.delete(Const.EMAIL_VALIDATION_CODE + mail);
            redisUtils.set(Const.EMAIL_VALIDATION_CODE + mail, code, TimeEnum.MINUTE.getTime(5) / 1000);
            MailManager.sendMailCode(mail, code);
            redisUtils.set(Const.EMAIL_VALIDATION_TIMEOUT + mail, System.currentTimeMillis(), TimeEnum.MINUTE.getTime(1) / 1000);
            if (hasSendCount == 0) {
                redisUtils.set(Const.EMAIL_VALIDATION_COUNT + mail, 1, TimeUtil.getTime2NextDay());
            } else {
                redisUtils.increment(Const.EMAIL_VALIDATION_COUNT + mail, 1);
            }
            log.info("向【{}】发送验证码完毕！", mail);
            RabbitHelper.execute(message);
        } catch (Exception e) {
            e.printStackTrace();
            RabbitHelper.receive(message, e);
        } finally {
            // ACK
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
    }

}
